using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.ComponentModel;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;

using SandcastleBuilder.Utils;
using SandcastleBuilder.Utils.PlugIn;

namespace Darilek.SandcastleExtensions.PlugIns
{
	public class Help2RegistrationPlugIn  : IPlugIn
	{
		private ExecutionPointCollection _executionPoints;
		private BuildProcess _buildProcess;

		#region IPlugIn Members

		public string ConfigurePlugIn(string currentConfig)
		{
			//throw new Exception("The method or operation is not implemented.");
			MessageBox.Show("This plugin does not need any configuration", "Help2RegistrationPlugIn", MessageBoxButtons.OK, MessageBoxIcon.Information);
			return currentConfig;
		}

		public string Copyright
		{
			get
			{
				Assembly asm = Assembly.GetExecutingAssembly();
				AssemblyCopyrightAttribute copyright =
					(AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(
						asm, typeof(AssemblyCopyrightAttribute));

				return copyright.Copyright;
			}
		}

		public string Description
		{
			get 
			{
				return "Generates a set of Help2 collection (HxC), TOC (HxT) and index (HxK) files to register help documentation with H2Reg utility";
			}
		}

		public void Execute(ExecutionContext context)
		{
			string htmlHelpName = _buildProcess.CurrentProject.HtmlHelpName;

			_buildProcess.ReportProgress("Info: Generating Help2 registration files");

			ApplyTransformation("h2reg.HxC", htmlHelpName + ".HxC");
			ApplyTransformation("h2reg.HxT", htmlHelpName + ".HxT");
			ApplyTransformation("h2reg_A.HxK", htmlHelpName + "_A.HxK");
			ApplyTransformation("h2reg_B.HxK", htmlHelpName + "_B.HxK" );
			ApplyTransformation("h2reg_F.HxK", htmlHelpName + "_F.HxK");
			ApplyTransformation("h2reg_K.HxK", htmlHelpName + "_K.HxK");
			ApplyTransformation("h2reg_N.HxK", htmlHelpName + "_N.HxK");
			ApplyTransformation("h2reg_S.HxK", htmlHelpName + "_S.HxK");
			ApplyTransformation("h2reg.ini", "h2reg.ini");

			context.Executed = true;
		}

		public ExecutionPointCollection ExecutionPoints
		{
			get
			{
				if (_executionPoints == null)
				{
					_executionPoints = new ExecutionPointCollection();
					_executionPoints.Add(new ExecutionPoint(BuildStep.CompilingHelpFile, ExecutionBehaviors.After));
				}

				return _executionPoints;

			}
		}

		public void Initialize(BuildProcess buildProcess, XPathNavigator configuration)
		{
			_buildProcess = buildProcess;

		}

		public string Name
		{
			get { return "Help2 Registration PlugIn"; }
		}

		public bool RunsInPartialBuild
		{
			get { return true; }
		}

		public Version Version
		{
			get
			{
				// Use the assembly version
				Assembly asm = Assembly.GetExecutingAssembly();
				FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(
					asm.Location);

				return new Version(fvi.ProductVersion);
			}
		}

		#endregion

		#region IDisposable Members

        //=====================================================================
        // IDisposable implementation

        /// <summary>
        /// This handles garbage collection to ensure proper disposal of the
        /// plug-in if not done explicity with <see cref="Dispose()"/>.
        /// </summary>
		~Help2RegistrationPlugIn()
        {
            this.Dispose(false);
        }

        /// <summary>
        /// This implements the Dispose() interface to properly dispose of
        /// the plug-in object.
        /// </summary>
        /// <overloads>There are two overloads for this method.</overloads>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// This can be overridden by derived classes to add their own
        /// disposal code if necessary.
        /// </summary>
        /// <param name="disposing">Pass true to dispose of the managed
        /// and unmanaged resources or false to just dispose of the
        /// unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            // TODO: Implement this if necessary
        }
        #endregion

		private void ApplyTransformation(string inputFileName, string outputFileName)
		{
			string inputFilePath = _buildProcess.TemplateFolder + inputFileName;
			string tempFilePath = _buildProcess.WorkingFolder + inputFileName;
			string outputFilePath = _buildProcess.OutputFolder + outputFileName;

			_buildProcess.TransformTemplate(inputFileName, _buildProcess.TemplateFolder, _buildProcess.WorkingFolder);

			if (File.Exists(outputFilePath))
			{
				_buildProcess.ReportProgress("Warning: File '{0}' already exists. It will be replaced.", outputFileName);
				File.Delete(outputFilePath);
			}

			File.Move(tempFilePath, outputFilePath);
		}
	}
}
